package com.rtsapp.agent;

import com.rtsapp.agent.handler.HotfixHandler;
import com.rtsapp.agent.rules.HotfixInitCallBack;
import com.rtsapp.server.logger.Logger;
import com.rtsapp.server.logger.LoggerFactory;

import java.lang.instrument.Instrumentation;

/**
 * Created by liwang on 17-3-20.
 */
public final class HotfixService {

    private static final Logger LOGGER = LoggerFactory.getLogger( HotfixService.class );

    protected static final HotfixHandler AGENT_HANDLER = new HotfixHandler( );

    private static Instrumentation inst = null;

    /**
     * 执行agent初始化操作
     * <p>
     * 1. 如果已经初始化, 或另一个初始化任务正在执行, 直接返回状态值
     * 2. 如果未初始化, 则执行初始化操作
     *
     * @return
     */
    public static void initialize( ) {
        initialize( null );
    }

    public static void initialize( HotfixInitCallBack callBack ) {
        AgentLoader.loadAgent( new AgentLoader.LoadAgentCallBack( ) {
            @Override
            public void callBack( Instrumentation inst ) {
                HotfixService.inst = inst;

                AGENT_HANDLER.initialize( inst );

                if ( callBack != null ) {
                    callBack.callback( inst != null );
                }
            }
        } );
    }


    /**
     * 启动 hotfix 定时任务
     *
     * @param period 定时任务的时间间隔, 必须大于0, 单位: 秒
     * @param rules
     */
    public static boolean startHotFixTimeTask( int period, String... rules ) {
        return AGENT_HANDLER.setHotFixTimeTask( period, rules );
    }

    /**
     * 取消定时修复任务
     *
     * @param mayInterruptIfRunning 是否终端正在执行的任务
     */
    public static void cancelHotFixTimeTask( boolean mayInterruptIfRunning ) {
        AGENT_HANDLER.cancelHotFixTimeTask( mayInterruptIfRunning );
    }

    /**
     * 手动执行一次热更新
     *
     * @return false代表热更新功能未初始化, true代表成功调用, 并不代表成功执行完
     */
    public static boolean runHotFixOnce( String... rules ) {
        return AGENT_HANDLER.runHotFixOnce( rules );
    }


    /**
     * 获得agent的Instrumentation实例, 用于对虚拟机进行一些操作
     *
     * @return null:代理未加载
     */
    public static Instrumentation getAgentInstrumentation( ) {
        return inst;
    }


}
